<?php

namespace Trawind\VerifyPermission\Middleware;

use Closure;
use Illuminate\Http\Request;
use Trawind\VerifyPermission\VerifyPermission;
use Illuminate\Support\Facades\Route;
use Illuminate\Auth\AuthenticationException;
use Trawind\Basics\Exceptions\ForbiddenException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Request as FacadesRequest;
use Trawind\Basics\Exceptions\LogicException;
use Trawind\Helpers\UserHelper;
use Trawind\Remotes\Repositories\User\ResourcesRepositoryEloquent;
use Trawind\Remotes\Repositories\User\ResourceOperationsRepositoryEloquent;

class CheckOperactionPermission
{
    public $controller = '';
    public $action = '';
    public $ignore = [
    
    ];

    public function handle(Request $request, Closure $next, $userIgnore = null)
    {
        $this->makeRoute();

        if ($userIgnore)
            $this->ignore = array_merge_recursive($this->ignore, json_decode(base64_decode($userIgnore), true));
        
        if(! $this->checkOperactionPermission()) {
            $ResourcesRepositoryEloquent = new ResourcesRepositoryEloquent();
            $cons = $ResourcesRepositoryEloquent->getListBySearch(['search' => "controller_identifier:{$this->controller}"]);
            $ResourcesRepositoryEloquent = new ResourceOperationsRepositoryEloquent();
            $acts = null;
            if ($cons['data'][0] ?? null) {
                $acts = $ResourcesRepositoryEloquent->getListBySearch([
                    'search' => "resource_id:{$cons['data'][0]['id']};action_identifier:{$this->action}", 
                    'searchJoin' => 'and'

            ]);
            }
            throw new ForbiddenException(___('no permission access.', ['action'=> ($cons['data'] ? $cons['data'][0] ? $cons['data'][0]['name'] : $this->controller : $this->controller).'-'. ($acts['data'] ? $acts['data'][0] ? $acts['data'][0]['name'] : $this->action : $this->action)]));
        }
        
        $response = $next($request);
        return $response;
    }

    public function checkOperactionPermission(): ?bool
    {
        // if in ignore Action don't check permissions
        if ($this->ignoreAction($this->controller, $this->action))
            return true;
        $verifyPermission = new VerifyPermission();
        if ($verifyPermission->ignoreVerify())
            return true;
        $verifyPermission->acls = $verifyPermission->permissions();
        return $verifyPermission->hasOperationPermission($this->controller, $this->action);
    }

    public function ignoreAction($controller, $action)
    {
        $actions = $this->ignore[$controller] ?? [];
        if (in_array($action, $actions))
            return true;
        return false;
    }

    public function makeRoute()
    {
        $routeAction = Route::currentRouteAction();
        $this->controller = explode('@',$routeAction)[0];
        $this->action = explode('@', $routeAction)[1];
    }
}